package org.unidata.mdm.meta.context;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Objects;

import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.unidata.mdm.core.context.AbstractModelChangeContext;
import org.unidata.mdm.core.service.segments.ModelUpsertStartExecutor;
import org.unidata.mdm.meta.configuration.TypeIds;
import org.unidata.mdm.meta.type.model.enumeration.EnumerationType;
import org.unidata.mdm.meta.util.ModelUtils;

/**
 * @author Mikhail Mikhailov on Oct 8, 2020
 */
public class UpsertEnumerationsContext extends AbstractModelChangeContext {
    /**
     * GSVUID.
     */
    private static final long serialVersionUID = 7169865700344716584L;
    /**
     * Enumerations updates.
     */
    private final List<EnumerationType> enumerationsUpdate;
    /**
     * Enumerations deletes.
     */
    private final List<String> enumerationsDelete;
    /**
     * Constructor.
     */
    private UpsertEnumerationsContext(UpsertEnumerationsContextBuilder b) {
        super(b);
        this.enumerationsUpdate = Objects.isNull(b.enumerationsUpdate) ? Collections.emptyList() : b.enumerationsUpdate;
        this.enumerationsDelete = Objects.isNull(b.enumerationsDelete) ? Collections.emptyList() : b.enumerationsDelete;
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public String getTypeId() {
        return TypeIds.ENUMERATIONS_MODEL;
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public String getInstanceId() {
        // Enumerations are singletons per storage id
        return ModelUtils.DEFAULT_MODEL_INSTANCE_ID;
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public String getStartTypeId() {
        return ModelUpsertStartExecutor.SEGMENT_ID;
    }
    /**
     * @return the enumerationsUpdate
     */
    public List<EnumerationType> getEnumerationsUpdate() {
        return enumerationsUpdate;
    }
    /**
     * @return the enumerationsDelete
     */
    public List<String> getEnumerationsDelete() {
        return enumerationsDelete;
    }

    public static UpsertEnumerationsContextBuilder builder() {
        return new UpsertEnumerationsContextBuilder();
    }
    /**
     * @author Mikhail Mikhailov on Oct 9, 2020
     */
    public static class UpsertEnumerationsContextBuilder extends AbstractModelChangeContextBuilder<UpsertEnumerationsContextBuilder> {
        /**
         * Enumerations updates.
         */
        private List<EnumerationType> enumerationsUpdate;
        /**
         * Enumerations deletes.
         */
        private List<String> enumerationsDelete;
        /**
         * Constructor.
         */
        private UpsertEnumerationsContextBuilder() {
            super();
        }

        public UpsertEnumerationsContextBuilder update(EnumerationType... ss) {
            if (ArrayUtils.isNotEmpty(ss)) {
                return update(Arrays.asList(ss));
            }
            return self();
        }

        public UpsertEnumerationsContextBuilder update(Collection<EnumerationType> ss) {
            if (CollectionUtils.isNotEmpty(ss)) {
                if (enumerationsUpdate == null) {
                    enumerationsUpdate = new ArrayList<>();
                }

                enumerationsUpdate.addAll(ss);
            }
            return self();
        }

        public UpsertEnumerationsContextBuilder delete(String... ss) {
            if (ArrayUtils.isNotEmpty(ss)) {
                return delete(Arrays.asList(ss));
            }
            return self();
        }

        public UpsertEnumerationsContextBuilder delete(Collection<String> ss) {
            if (CollectionUtils.isNotEmpty(ss)) {
                if (enumerationsDelete == null) {
                    enumerationsDelete = new ArrayList<>();
                }

                enumerationsDelete.addAll(ss);
            }
            return self();
        }
        /**
         * {@inheritDoc}
         */
        @Override
        public UpsertEnumerationsContext build() {
            return new UpsertEnumerationsContext(this);
        }
    }
}
